# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: site-packages\PyInstaller\building\osx.py
import codecs, os, shutil
from ..compat import is_darwin, FileExistsError
from .api import EXE, COLLECT
from .datastruct import Target, TOC, logger, _check_guts_eq
from .utils import _check_path_overlap, _rmtree, add_suffix_to_extensions, checkCache


class BUNDLE(Target):
    def __init__(self, *args, **kws):
        from ..config import CONF

        if not is_darwin:
            return
        self.icon = kws.get("icon")
        if not self.icon:
            self.icon = os.path.join(
                os.path.dirname(os.path.dirname(__file__)),
                "bootloader",
                "images",
                "icon-windowed.icns",
            )
        self.icon = os.path.abspath(self.icon)
        Target.__init__(self)
        self.name = kws.get("name", None)
        base_name = os.path.basename(self.name)
        self.name = os.path.join(CONF["distpath"], base_name)
        self.appname = os.path.splitext(base_name)[0]
        self.version = kws.get("version", "0.0.0")
        self.toc = TOC()
        self.strip = False
        self.upx = False
        self.bundle_identifier = kws.get("bundle_identifier")
        if not self.bundle_identifier:
            self.bundle_identifier = self.appname
        self.info_plist = kws.get("info_plist", None)
        for arg in args:
            if isinstance(arg, EXE):
                self.toc.append((os.path.basename(arg.name), arg.name, arg.typ))
                self.toc.extend(arg.dependencies)
                self.strip = arg.strip
                self.upx = arg.upx
            elif isinstance(arg, TOC):
                self.toc.extend(arg)
            elif isinstance(arg, COLLECT):
                self.toc.extend(arg.toc)
                self.strip = arg.strip_binaries
                self.upx = arg.upx_binaries
            else:
                logger.info("unsupported entry %s", arg.__class__.__name__)

        for inm, name, typ in self.toc:
            if typ == "EXECUTABLE":
                self.exename = name
                if self.name is None:
                    self.appname = "Mac%s" % (os.path.splitext(inm)[0],)
                    self.name = os.path.join(CONF["specpath"], self.appname + ".app")
                else:
                    self.name = os.path.join(CONF["specpath"], self.name)
                break

        self.__postinit__()

    _GUTS = (("toc", None),)

    def _check_guts(self, data, last_build):
        return 1

    def assemble(self):
        if _check_path_overlap(self.name):
            if os.path.isdir(self.name):
                _rmtree(self.name)
        logger.info("Building BUNDLE %s", self.tocbasename)
        os.makedirs(os.path.join(self.name, "Contents", "MacOS"))
        os.makedirs(os.path.join(self.name, "Contents", "Resources"))
        os.makedirs(os.path.join(self.name, "Contents", "Frameworks"))
        if os.path.exists(self.icon):
            shutil.copy(self.icon, os.path.join(self.name, "Contents", "Resources"))
        else:
            logger.warning("icon not found %s", self.icon)
        info_plist_dict = {
            "CFBundleDisplayName": self.appname,
            "CFBundleName": self.appname,
            "CFBundleIdentifier": self.bundle_identifier,
            "CFBundleExecutable": "MacOS/%s" % os.path.basename(self.exename),
            "CFBundleIconFile": os.path.basename(self.icon),
            "CFBundleInfoDictionaryVersion": "6.0",
            "CFBundlePackageType": "APPL",
            "CFBundleShortVersionString": self.version,
            "LSBackgroundOnly": "0",
        }
        if isinstance(self.info_plist, dict) and self.info_plist:
            info_plist_dict.update(self.info_plist)
        info_plist = '<?xml version="1.0" encoding="UTF-8"?>\n<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n<plist version="1.0">\n<dict>'
        for k, v in info_plist_dict.items():
            info_plist += "<key>%s</key>\n<string>%s</string>\n" % (k, v)

        info_plist += "</dict>\n</plist>"
        with codecs.open(
            os.path.join(self.name, "Contents", "Info.plist"), "w", "utf-8"
        ) as (f):
            f.write(info_plist)
        links = []
        toc = add_suffix_to_extensions(self.toc)
        for inm, fnm, typ in toc:
            if typ in ("EXTENSION", "BINARY"):
                fnm = checkCache(fnm, strip=self.strip, upx=self.upx, dist_nm=inm)
            if typ == "DATA":
                links.append((inm, fnm))
            else:
                tofnm = os.path.join(self.name, "Contents", "MacOS", inm)
                todir = os.path.dirname(tofnm)
                if not os.path.exists(todir):
                    os.makedirs(todir)
                shutil.copy(fnm, tofnm)

        logger.info("moving BUNDLE data files to Resource directory")
        bin_dir = os.path.join(self.name, "Contents", "MacOS")
        res_dir = os.path.join(self.name, "Contents", "Resources")
        for inm, fnm in links:
            if inm != "base_library.zip":
                tofnm = os.path.join(res_dir, inm)
                todir = os.path.dirname(tofnm)
                if not os.path.exists(todir):
                    os.makedirs(todir)
                shutil.copy(fnm, tofnm)
                base_path = os.path.split(inm)[0]
                if base_path:
                    if not os.path.exists(os.path.join(bin_dir, inm)):
                        path = ""
                        for part in iter(base_path.split(os.path.sep)):
                            path = os.path.join(path, part)
                            try:
                                relative_source_path = os.path.relpath(
                                    os.path.join(res_dir, path),
                                    os.path.split(os.path.join(bin_dir, path))[0],
                                )
                                dest_path = os.path.join(bin_dir, path)
                                os.symlink(relative_source_path, dest_path)
                                break
                            except FileExistsError:
                                pass

                        if not os.path.exists(os.path.join(bin_dir, inm)):
                            relative_source_path = os.path.relpath(
                                os.path.join(res_dir, inm),
                                os.path.split(os.path.join(bin_dir, inm))[0],
                            )
                            dest_path = os.path.join(bin_dir, inm)
                            os.symlink(relative_source_path, dest_path)
                        else:
                            os.symlink(
                                os.path.relpath(
                                    os.path.join(res_dir, inm),
                                    os.path.split(os.path.join(bin_dir, inm))[0],
                                ),
                                os.path.join(bin_dir, inm),
                            )
                    else:
                        shutil.copy(fnm, bin_dir)
